#include "StdAfx.h"
#include "AdditiveSynthInstrument.h"
#include "Notes.h"


CAdditiveSynthInstrument::CAdditiveSynthInstrument(void)
{
}


CAdditiveSynthInstrument::~CAdditiveSynthInstrument(void)
{
}

void CAdditiveSynthInstrument::Start()
{
    m_adsr.SetSampleRate(GetSampleRate());
	m_adsr.SetBPM(m_bpm);
	m_adsr.SetAttack(m_attack);
	m_adsr.SetDecay(m_decay);
	m_adsr.SetRelease(m_release);
	m_adsr.Start();

    m_time = 0;

	m_addSynth.SetSampleRate(GetSampleRate());
	m_addSynth.SetBPM(m_bpm);
    m_addSynth.Start();
    m_adsr.SetSource(&m_addSynth);
}

void CAdditiveSynthInstrument::SetNote(CNote *note)
{
    // Get a list of all attribute nodes and the
    // length of that list
    CComPtr<IXMLDOMNamedNodeMap> attributes;
    note->Node()->get_attributes(&attributes);
    long len;
    attributes->get_length(&len);

    // Loop over the list of attributes
    for(int i=0;  i<len;  i++)
    {
        // Get attribute i
        CComPtr<IXMLDOMNode> attrib;
        attributes->get_item(i, &attrib);

        // Get the name of the attribute
        CComBSTR name;
        attrib->get_nodeName(&name);

        CComVariant value;
        attrib->get_nodeValue(&value);

        if(name == "duration")
        {
            value.ChangeType(VT_R8);
            SetDuration(value.dblVal);
        }
        else if(name == "note")
        {
            SetFreq(NoteToFrequency(value.bstrVal));
        }
    }

}

bool CAdditiveSynthInstrument::Generate()
{
	m_addSynth.Generate();

    bool valid = m_adsr.Generate();

    m_frame[0] = m_adsr.Frame(0);
    m_frame[1] = m_adsr.Frame(1);

    m_time += GetSamplePeriod();
    return valid;
}